class_name CustomTimer

## Timer

enum TimerState
{
	UnInit,
	Idle,
	Pausing,
	Processing,
	Finished,
}
enum TimerResult
{
	Cancel,
	Completed,
}
#region 属性
var id:int
var start_time:int
var duration:float
# 无限循环用-1
var repeat_count:int
var left_time:float
var left_repeat_count:int
var timer_state:TimerState = TimerState.UnInit
var connect_obj_dict:Dictionary
#endregion
#region 字段
## Timer实际运行时间
var running_real_time:float:
	get:
		return Time.get_ticks_msec() - start_time
## Timer不包含暂停运行时间
var running_time_no_pause:float:
	get:
		return left_time + (repeat_count - left_repeat_count) * duration
## Timer不包含暂停总时间
var total_time_no_pause:float:
	get:
		return repeat_count * duration
## 进度[0,1]
var progress:float:
	get:
		if repeat_count < 0:
			return 0
		return running_time_no_pause / total_time_no_pause
#endregion
#region 信号
signal timer_start
signal timer_pause
signal timer_tick
signal timer_reset
signal timer_done(idx:int)
signal timer_finished(timer_result:TimerResult)
#endregion

#region 基类方法
#endregion
#region 公共方法
## 开始
func start_timer():
	if timer_state not in [TimerState.Idle,TimerState.Pausing]:
		return
	if timer_state == TimerState.Idle:
		start_time = Time.get_ticks_msec()
	elif timer_state == TimerState.Pausing:
		pass
	timer_state = TimerState.Processing
	timer_start.emit()
## 暂停
func pause_timer():
	if timer_state != TimerState.Processing:
		return
	timer_state = TimerState.Pausing
	timer_pause.emit()
## 停止
func stop_timer(is_completed:bool = false):
	if timer_state != TimerState.Processing:
		return
	timer_state = TimerState.Finished
	timer_finished.emit(TimerResult.Cancel if not is_completed else TimerResult.Completed)
	GameCustomTimerSystem.remove_timer(id)
## 重置
func reset_timer():
	left_time = duration
	left_repeat_count = repeat_count
	timer_reset.emit()
func tick(delta_time):
	if timer_state != TimerState.Processing:
		return
	left_time -= delta_time
	timer_tick.emit()
	if left_time <= 0:
		timer_done.emit(repeat_count - left_repeat_count)
		left_repeat_count -= 1 if repeat_count > 0 else 0
		if left_repeat_count == 0:
			stop_timer(true)
		else:
			left_time = duration
func register_listener(si:Signal,f:Callable,connect_flag:int = 0):
	if not get_signal_list().any(func(x):return x.name == si.get_name()):
		return
	if not connect_obj_dict.has(si.get_name()):
		connect_obj_dict[si.get_name()] = ConnectObj.new(si)
	connect_obj_dict[si.get_name()].connect_single(f,connect_flag)
func destroy():
	stop_timer(false)
	for connect_obj:ConnectObj in connect_obj_dict.values():
		if connect_obj:
			connect_obj.disconnect_all()
#endregion
#region 私有方法
#endregion
#region 生命周期函数
func _init(id:int,duration:float,repeat_count:int = 1) -> void:
	self.timer_state = TimerState.UnInit
	self.id = id
	self.duration = duration
	self.left_time = self.duration
	self.repeat_count = repeat_count
	self.left_repeat_count = self.repeat_count
	self.timer_state = TimerState.Idle
#endregion
